package com.codecorp.cortex_scan;

import com.codecorp.CortexDecoderLibrary;
import com.codecorp.CortexDecoderLibrary.CortexDecoderLibraryCallback;
import com.codecorp.CortexDecoderLibrary.SymbologyType;
import com.codecorp.CortexDecoderLibrary.CortexDecoderLicenseCallback;
import com.codecorp.CortexDecoderLibrary.LicenseStatusCode;
import com.codecorp.internal.Debug;
import static com.codecorp.internal.Debug.*;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.text.Html;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.util.Map.Entry;
import com.example.ht380d4G_jar_demo.R;
public class CortexScan extends Activity implements CortexDecoderLibraryCallback, CortexDecoderLicenseCallback {

    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
    };

    static final String TAG = CortexScan.class.getSimpleName();
    static final String LTAG = "CORTEXLMGR";
    private SharedPreferences prefs;
    private CortexDecoderLibrary mCortexDecoderLibrary;
    private TextView mBarcodeResult;
    private TextView mBarcodeLength;
    private TextView mSymbologyResult;
    private View mCameraPreview;
    private TextView mTap;
    private TextView mLicense;
    private CrosshairsView mCrosshairs;
    private MyApplication mApplication;
    private FrameLayout mCameraFrame;
    private Handler mMainHandler;

    @Override
    public void onCreate(Bundle state) {

        PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
        prefs = PreferenceManager.getDefaultSharedPreferences(this);

        if (!prefs.contains("focus.Back-Facing")) {
            setPreference(prefs, "focus.Back-Facing", "Normal");
        }
        if (!prefs.contains("illumination.Back-Facing")) {
            setPreference(prefs, "illumination.Back-Facing", false);
        }
        if (!prefs.contains("focus.Front-Facing")) {
            setPreference(prefs, "focus.Front-Facing", "Far Fixed");
        }
        if (!prefs.contains("illumination.Front-Facing")) {
            setPreference(prefs, "illumination.Front-Facing", false);
        }

        if (!prefs.contains("data_matrix")) {
            setPreference(prefs, "data_matrix", true);
        }

        if (!prefs.contains("gs1_databar")) {
            setPreference(prefs, "gs1_databar", true);
        }

        if (!prefs.contains("code11")) {
            setPreference(prefs, "code11", false);
        }

        mApplication = (MyApplication) getApplication();
        mApplication.pushPreference(prefs, "debug_level");
        // Uncomment a line below to override the debug level
        // setDebugLevel(Log.INFO);
        // setDebugLevel(Log.DEBUG);
        // setDebugLevel(Log.VERBOSE);

        debug(TAG, "onCreate()");

        verbose(TAG, "MANUFACTURER: " + android.os.Build.MANUFACTURER);
        verbose(TAG, "MODEL: " + android.os.Build.MODEL);
        verbose(TAG, "BRAND: " + android.os.Build.BRAND);
        verbose(TAG, "DEVICE: " + android.os.Build.DEVICE);
        verbose(TAG, "HARDWARE: " + android.os.Build.HARDWARE);
        verbose(TAG, "FINGERPRINT: " + android.os.Build.FINGERPRINT);
        verbose(TAG, "PRODUCT: " + android.os.Build.PRODUCT);
        verbose(TAG, "ID: " + android.os.Build.ID);
        verbose(TAG, "HOST: " + android.os.Build.HOST);

        super.onCreate(state);
        setContentView(R.layout.main_view);
        mBarcodeResult = (TextView) findViewById(R.id.barcode_result);
        mBarcodeLength = (TextView) findViewById(R.id.length_result);
        mSymbologyResult = (TextView) findViewById(R.id.symbology_result);
        // Use the Application context, which is shared by this activity
        // and the settings activity.
        mCortexDecoderLibrary = CortexDecoderLibrary.sharedObject(mApplication);
//        if(!mCortexDecoderLibrary.isDeviceLicensed()){
//        	Toast.makeText(this, getString(R.string.device_not_licensed_test),Toast.LENGTH_SHORT).show();
//        	 Intent intent = new Intent();
//				intent.setClassName("com.codecorp.cortex_scan","com.codecorp.cortex_scan.CortexScan");
//				startActivity(intent);
//				finish();
//				return;      	
//        }
        // Save mCortexDecoderLibrary in case another Activity needs it
        mApplication.mCortexDecoderLibrary = mCortexDecoderLibrary;
        mCortexDecoderLibrary.setCallback(this);
        // If manual auto focus required uncomment the following 2 lines.
        // mCortexDecoderLibrary.setManualAutoFocus();
        // mCortexDecoderLibrary.setAutoFocusInterval(500);
        mCameraPreview = mCortexDecoderLibrary.getCameraPreview();
        mCameraFrame = (FrameLayout) findViewById(R.id.cortex_scanner_view);
        mCameraFrame.addView(mCameraPreview, 0);
        mTap = (TextView) findViewById(R.id.tap_to_scan_again);
        mLicense = (TextView) findViewById(R.id.device_not_licensed);
        mLicense.setVisibility(View.INVISIBLE);
        mCrosshairs = (CrosshairsView) findViewById(R.id.crosshairs_view);

        // Verify permission to read external storage for licensing
        if (verifyStoragePermissions(CortexScan.this)) {
            mCortexDecoderLibrary.initLicensing("/mnt/sdcard",this);
        }

        // Send all preferences to decoder
        pushPreferences();
        mMainHandler = new Handler(Looper.getMainLooper());
    }

    private void setPreference(SharedPreferences sharedPreferences,
                               String key, Object value) {
        debug(TAG, "setPreference(" + key + ", " + value + ")");
        SharedPreferences.Editor e = sharedPreferences.edit();
        if (value instanceof String)
            e.putString(key, (String) value);
        else if (value instanceof Boolean)
            e.putBoolean(key, (Boolean) value);
        else
            throw new RuntimeException("Programming error!  Unknown value type.");
        e.apply();
    }

    private void setDebugLevel(int level) {
        Log.d(TAG, "setDebugLevel(" + level + ")");
        Debug.debugLevel = level;
        Editor e = prefs.edit();
        e.putString("debug_level", Integer.toString(level));
        e.apply();
    }

    private void pushPreferences() {
        for (Entry<String, ?> e : prefs.getAll().entrySet()) {
            try {
                mApplication.pushPreference(prefs, e.getKey());
            } catch (Exception ex) {
                Log.e(TAG, "Error pushing preference " + e.getKey() + ":", ex);
            }
        }
    }

    OnClickListener tapListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            debug(TAG, "onClick()");
            mBarcodeResult.setText("");
            mBarcodeLength.setText("");
            mSymbologyResult.setText("");
            startScanning();
        }
    };

    void startScanning() {
        debug(TAG, "startScanning()");
        mCrosshairs.setVisibility(View.VISIBLE);
        mTap.setVisibility(View.INVISIBLE);
        mCameraFrame.setOnClickListener(null);
        // This can take a while if we need to open the camera, so post
        // it after the UI update.
        mMainHandler.post(new Runnable() {
            @Override
            public void run() {
                mCortexDecoderLibrary.startCameraPreview();
                mCortexDecoderLibrary.startDecoding();
            }
        });
    }

    void stopScanning() {
        debug(TAG, "stopScanning()");
        mCrosshairs.setVisibility(View.INVISIBLE);
        mTap.setVisibility(View.VISIBLE);
        mCortexDecoderLibrary.stopDecoding();
        mCameraFrame.setOnClickListener(tapListener);
        mCortexDecoderLibrary.stopCameraPreview();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuItem menuItem;
        menuItem = menu.add(Menu.NONE, R.id.menu_about, 0, R.string.info);
        menuItem.setIcon(android.R.drawable.ic_dialog_info);
        menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        menuItem = menu.add(Menu.NONE, R.id.menu_settings, 3, R.string.settings);
        menuItem.setIcon(R.drawable.ic_menu_settings_alpha);
        menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        return super.onCreateOptionsMenu(menu);
    }

    public void stopCamera() {
        debug(TAG, "stopCamera()");
        mCortexDecoderLibrary.stopDecoding();
        mCortexDecoderLibrary.stopCameraPreview();
    }

    public void closeCamera() {
        debug(TAG, "closeCamera()");
        mCortexDecoderLibrary.stopDecoding();
        mCortexDecoderLibrary.stopCameraPreview();
        mCortexDecoderLibrary.closeCamera();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.menu_settings) {
            // Launch the preferences activity
            Intent intent = new Intent();
            stopCamera();
            intent.setClass(this, SettingsActivity.class);
            startActivity(intent);
            return true;
        } else if (item.getItemId() == R.id.menu_about) {
            stopCamera();
            // Launch the information activity
            Intent intent = new Intent();
            intent.setClass(this, InformationActivity.class);
            startActivity(intent);
            return true;
        } else {
            return super.onOptionsItemSelected(item);
        }
    }

    AlertDialog createInfoDialog(String title, String message) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage(Html.fromHtml(message));
        builder.setTitle(title);
        builder.setIcon(android.R.drawable.ic_dialog_info);
        builder.setPositiveButton(R.string.ok_button, null);
        return builder.create();
    }

    void checkLicensing() {
        if (mLicense != null && mCortexDecoderLibrary != null) {
            if (mCortexDecoderLibrary.isDeviceLicensed()) {
                mLicense.setVisibility(View.INVISIBLE);
            } else {
                mLicense.setVisibility(View.VISIBLE);
            }
        } else {
            mLicense.setVisibility(View.INVISIBLE);
        }
    }

    @Override
    protected void onStart() {
        debug(TAG, "onStart()");
        super.onStart();
    }

    @Override
    public void onResume() {
        debug(TAG, "onResume()");
        super.onResume();
        pushPreferences();
        mCortexDecoderLibrary.setLicenseCallback(this);
        checkLicensing();
        startScanning();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        debug(TAG, "onActivityResult()");
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onPause() {
        debug(TAG, "onPause()");
        super.onPause();
        mCortexDecoderLibrary.setLicenseCallback(null);
        stopCamera();
        closeCamera();
    }

    @Override
    public void onStop() {
        debug(TAG, "onStop()");
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        debug(TAG, "onDestroy()");
        mCortexDecoderLibrary.closeSharedObject();
        super.onDestroy();
    }

    @Override
    public void receivedDecodedData(final String data, final SymbologyType type) {
        debug(TAG, "receivedDecodedData()");
        final String symString = CortexDecoderLibrary.stringFromSymbologyType(type);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (!prefs.getBoolean("large_data_display", false)) {
                    // final String tdata = data.substring(0, Math.min(data.length(), 10));
                    mBarcodeResult.setText(data);
                    mBarcodeLength.setText(String.valueOf(data.length()));
                    mSymbologyResult.setText(symString);
                    if (!prefs.getBoolean("continuous_scan_mode", false)) {
                        stopScanning();
                    } else {
                        mCortexDecoderLibrary.startDecoding();
                    }
                } else {
                    // Launch the large data view activity
                    Intent intent = new Intent();
                    intent.setClass(CortexScan.this, LargeDataActivity.class);
                    intent.putExtra("symbology", symString);
                    intent.putExtra("barcode", data);
                    startActivityForResult(intent, 777);
                }
            }
        });
        boolean debugMode = prefs.getBoolean("debug_mode", false);
        if (debugMode) {
            // Save image from last barcode
            mCortexDecoderLibrary.captureCurrentImageInBuffer();
        }
    }

    @Override
    public void licenseStatusCallback(LicenseStatusCode statusCode) {
        final boolean deviceNotLicensed = (statusCode != LicenseStatusCode.LicenseStatus_LicenseValid);
        switch (statusCode) {
            case LicenseStatus_LicenseNotFound:
                // Log.i(LTAG, "License file does not exist on device");
                Toast.makeText(CortexScan.this, "License not found", Toast.LENGTH_LONG).show();
                break;
            case LicenseStatus_LicenseDeviceMismatch:
                // Log.i(LTAG, "License file does not match DeviceID or Wifi Mac Address of current device");
                Toast.makeText(CortexScan.this, "License device mismatch", Toast.LENGTH_LONG).show();
                break;
            case LicenseStatus_LicenseNetworkError:
                // Log.i(LTAG, "Encountered network error while trying to acquire license");
                Toast.makeText(CortexScan.this, "License network error", Toast.LENGTH_LONG).show();
                break;
            case LicenseStatus_LicenseInvalid:
                // Log.i(LTAG, "License does not exist on back-end server");
                Toast.makeText(CortexScan.this, "License invalid", Toast.LENGTH_LONG).show();
                break;
            case LicenseStatus_LicenseNotActivated:
                // Log.i(LTAG, "License has not been activated");
                Toast.makeText(CortexScan.this, "License not activated", Toast.LENGTH_LONG).show();
                break;
            case LicenseStatus_LicenseExpired:
                // Log.i(LTAG, "License has expired");
                Toast.makeText(CortexScan.this, "License expired", Toast.LENGTH_LONG).show();
                break;
            case LicenseStatus_LicenseBlocked:
                // Log.i(LTAG, "License has been blocked");
                Toast.makeText(CortexScan.this, "License blocked", Toast.LENGTH_LONG).show();
                break;
            case LicenseStatus_LicenseInternetBlocked:
                // Log.i(LTAG, "License has been blocked due to license not being validated");
                Toast.makeText(CortexScan.this, "License blocked due to no Internet", Toast.LENGTH_LONG).show();
                break;
            case LicenseStatus_LicenseBlockedNoCheckin:
                // Log.i(LTAG, "License has been blocked no check-in withing sync period");
                Toast.makeText(CortexScan.this, "License blocked no check-in", Toast.LENGTH_LONG).show();
                break;
            case LicenseStatus_LicenseValid:
                // Log.i(LTAG, "License is valid to use");
                Toast.makeText(CortexScan.this, "License valid for use", Toast.LENGTH_LONG).show();
                break;
            default:
                // Log.i(LTAG, "Received unknown license status code");
                Toast.makeText(CortexScan.this, "Received unknown license status code", Toast.LENGTH_LONG).show();
                break;
        }

        // update UI
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (deviceNotLicensed) {
                    mLicense.setVisibility(View.VISIBLE);
                } else {
                    mLicense.setVisibility(View.INVISIBLE);
                }
            }
        });
    }

    /**
     * Giving access for read storage permission for android version 6 and above
     *
     * @param activity activity of the class
     */
    public boolean verifyStoragePermissions(Activity activity) {
//        // Check if we have read permission
//    	if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.BASE){
//    	
//        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
//
//        if (permission == PackageManager.PERMISSION_GRANTED) {
//             Log.i(LTAG, "READ_EXTERNAL_STORAGE granted");
//            return true;
//        } else {
//             Log.i(LTAG, "READ_EXTERNAL_STORAGE not granted");
//            return false;
//        }
//    	}
    	
    	return true;
    }

}